﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mls.IO;
using System.IO;
using Mls.Interpreters;

namespace Mls
{
    public class Document
    {
        private string _filename;
        private Language.LanguageSettings _settings;
        private DocumentHeader _header;
        private List<Character> _data = new List<Character>();
        private int _readPosition = 0;

        public Language.LanguageSettings LanguageSettings { get { return _settings; } }
        public string Name { get { return Path.GetFileNameWithoutExtension(_filename); } }
        public string Filename { get { return _filename; } }
        public string PreviousDocument { get { return _header.PreviousDocument; } }
        public string NextDocument { get { return _header.NextDocument; } }

        public Document(string filename, Language.LanguageSettings settings)
        {
            _filename = filename;
            _settings = settings;

            BinaryReader reader = new BinaryReader(File.OpenRead(_filename));
            _header = DocumentHeader.Read(reader);

            while (true)
            {
                try
                {
                    ushort token = reader.ReadUInt16();

                    if (Character.IsFollowedByAccents(token))
                        _data.Add(new Character(_settings, token, reader.ReadUInt16()));
                    else
                        _data.Add(new Character(_settings, token));
                }
                catch (EndOfStreamException)
                {
                    break;
                }
            }

            reader.Close();
        }

        public Character Read
        {
            get
            {
                Character character = Ahead;

                if (character.Type != Token.EndOfFile)
                    Skip();

                return character;
            }
        }

        public Character Ahead
        {
            get
            {
                if (_readPosition >= _data.Count)
                    return Character.Eof;

                return ReadAhead(0);
            }
        }

        public Character ReadAhead(int i)
        {
            if (_readPosition + i >= _data.Count)
                return Character.Eof;

            return _data[_readPosition + i];
        }

        public void SeekBegining()
        {
            _readPosition = 0;
        }

        public void Skip()
        {
            _readPosition++;
        }
    }
}
